import {Observable, Subscription} from 'rxjs';

enum State {
  NEW,
  COMPLETING,
  NORMAL,
  EXCEPTIONAL,
  CANCELLED
}

export class Future<T> {
  private sub$: Subscription;
  // tslint:disable-next-line:variable-name
  // private _done = false;
  // tslint:disable-next-line:variable-name
  // private _cancelled = false;
  // tslint:disable-next-line:variable-name
  private _value: T;
  // tslint:disable-next-line:variable-name
  private _error: any;
  // tslint:disable-next-line:variable-name
  private _state: State;

  get isCancelled() {
    return this._state === State.CANCELLED;
  }

  get isDone() {
    return this._state !== State.NEW;
  }

  get isError() {
    return this._state === State.EXCEPTIONAL;
  }

  get value() {
    return this._value;
  }

  constructor(private observable: Observable<T>) {
    this._state = State.NEW;
    const self = this;
    this.sub$ = observable.subscribe({
      next(value) {
        self._value = value;
        self._state = State.COMPLETING;
        // console.log('next', value);
      },
      error(err) {
        self._error = err;
        self._state = State.EXCEPTIONAL;
        // console.log('error', err);
      },
      complete() {
        // console.log('complete');
        self._state = State.NORMAL;
      }
    });
  }

  cancel() {
    if (this._state === State.NEW) {
      this._state = State.CANCELLED;
      this.sub$.unsubscribe();
      this.sub$ = null;
    }
  }
}
